﻿using Microsoft.AspNetCore.Http;
using Microsoft.AspNetCore.Http.HttpResults;
using Microsoft.AspNetCore.Mvc;
using Microsoft.Data.SqlClient;
using Microsoft.EntityFrameworkCore.Metadata.Internal;
using Microsoft.Extensions.Hosting;
using MyWeb.ServiceBus.Common;
using MyWeb.ServiceBus.Model;
using MyWeb.ServiceBus.Services;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System.Collections.Specialized;
using System.Security.Policy;
using System.Text;
using System.Text.RegularExpressions;


using MyWeb.ServiceBus.Model.Models;
using System.Collections.Generic;
using MyWeb.ServiceBus.Services.Db;
using Microsoft.EntityFrameworkCore;

namespace MyWeb.ServiceBus.Controllers
{
    [Route("api/[controller]/[action]")]
    [ApiController]
    public class HttpRequstController : ControllerBase
    {
        private Context db;
        public HttpRequstController(Context context)
        {
            db = context;
        }


        [HttpGet]
        [HttpPost]
        [HttpPut]
        public async Task<IActionResult> Requst()
        {
            try
            {
                RequestLog log = new RequestLog();
                log.ForeStartTime = DateTime.Now;
                log.Headers = JsonConvert.SerializeObject(Request.Headers);
                
                string bodyData = string.Empty;
                using (StreamReader reader = new StreamReader(Request.Body, Encoding.UTF8))
                {
                    bodyData = reader.ReadToEndAsync().Result;
                }
                log.RequestLen = bodyData.Length;
                log.RequestParam = bodyData;
                // 解析 URL 参数
                NameValueCollection query = System.Web.HttpUtility.ParseQueryString(Request.QueryString.Value);


                var methon = Request.Method;

                string? ssdp = query["ssdp"];
                if (ssdp is null)
                {
                    return BadRequest(ApiResult.FAILED("ssdp is null"));
                }

                string urlData = "";

                foreach (var q in query)
                {
                    if (!q.Equals("ssdp"))
                    {
                        urlData = urlData + ((urlData.Length <= 0) ? "" : "&") + q.ToString() + "=" + query[q.ToString()];
                    }
                }

                // 解析 URL 参数
                NameValueCollection queryParams = System.Web.HttpUtility.ParseQueryString(Encrypt.Base64Decode(ssdp, "utf-8"));

                Param param = new Param()
                {
                    AppID = queryParams["AppID"],
                    ApiVersion = queryParams["ApiVersion"],
                    AppSubID = queryParams["AppSubID"],
                    AppToken = queryParams["AppToken"],
                    OrganiID = queryParams["OrganiID"],
                    Sign = queryParams["Sign"],
                    SysID = queryParams["SysID"],
                    TimeStamp = queryParams["TimeStamp"],
                    UserToken = queryParams["UserToken"]
                };

                var data = (from a in db.Application
                            join b in db.AppSystem on a.AppSystemId equals b.Id
                            join c in db.Organization on b.OrgId equals c.Id
                            where a.Code == param.AppSubID
                            select new
                            {
                                Application = a,
                                AppSystem = b,
                                Organization = c
                            }
                            ).First();
                //var data = await _db.Queryable<Application>()
                //    .InnerJoin<AppSystem>((a, s) => a.AppSystemId == s.Id)
                //    .InnerJoin<Organization>((a, s, o) => s.OrgId == o.Id)
                //    .Where(a => a.Code == param.AppSubID)
                //    .Select((a, s, o) => new { Application = a, AppSystem = s, Organization = o }).FirstAsync()
                //    ;
                if (data is null)
                {
                    return BadRequest(ApiResult.FAILED(msg: "AppSubID is not exists!"));
                }
                if (!data.Application.Sign.Equals(param.Sign))
                {
                    return BadRequest(ApiResult.FAILED(msg: "Sign is error!"));
                }
                if (!data.Application.AppToken.Equals(param.AppToken))
                {
                    return BadRequest(ApiResult.FAILED(msg: "AppToken is error!"));
                }
                if (!data.Organization.Code.Equals(param.OrganiID))
                {
                    return BadRequest(ApiResult.FAILED(msg: "OrganiID is error!"));
                }
                if (!data.AppSystem.Code.Equals(param.SysID))
                {
                    return BadRequest(ApiResult.FAILED(msg: "SysID is error!"));
                }
                log.CallerAppId = data.Application.Id;

                var server = await (from a in db.SysService
                                    join b in db.Gateway on a.Id equals b.ServiceId
                                    where a.Code == param.AppID && b.Version == param.ApiVersion
                                    select new
                                    {
                                        SysServer = a,
                                        Gateway = b
                                    }
                                     ).FirstAsync();


                //var server = await _db.Queryable<SysService>()
                //    .InnerJoin<Model.Models.Gateway>((s, g) => s.Id == g.ServiceId)
                //    .Where((s, g) => s.Code == param.AppID && g.Version == param.ApiVersion)
                //    .Select((s, g) => new { SysServer = s, Gateway = g })
                //    .FirstAsync();
                //log.ApplicationId = server.SysServer.ApplicationId;
                //log.SysServiceId = server.SysServer.Id;
                //log.GatewayId = server.Gateway.Id;

                if (server is null)
                {
                    return BadRequest(ApiResult.FAILED(msg: "AppID is not exists"));
                }
                // URL 正则表达式模式
                string pattern = @"^(https?|ftp)://[^\s/$.?#].[^\s]*$";

                // 使用 Regex.IsMatch 方法进行匹配
                if (!Regex.IsMatch(server.Gateway.ServiceUri, pattern))
                {
                    return BadRequest(ApiResult.FAILED(msg: "ServiceUri is not url"));
                }


                string url = server.Gateway.ServiceUri + (server.Gateway.ServiceUri.Contains("?") ? "&" : "?") + urlData;

                log.UrlReferrer = url;

                StringBuilder builder = new StringBuilder(url);
                //HttpClient httpClient = new HttpClient();
                log.RearStartTime = DateTime.Now;
                log.ForeEndTime = DateTime.Now;

                //var result = Redirect(builder.ToString());
                //return Redirect(builder.ToString());

                var result = await new MyHttpClient().GetAsync(builder.ToString());

                log.RearEndTime = DateTime.Now;
                log.ResultLen = result.Length;
                log.ResultParam = result;
                log.EsbCostTime = (log.ForeEndTime - log.ForeStartTime).TotalMilliseconds;
                log.CostTime = (log.RearEndTime - log.RearStartTime).TotalMilliseconds;
                //_db.CodeFirst.InitTables<RequestLog>();
                //log.Response = HttpContext.Request.Headers["name"];

                db.Add(log);
                await db.SaveChangesAsync();
                //await _db.Insertable(log).ExecuteCommandIdentityIntoEntityAsync();

                return Ok(ApiResult.SUCCESS(res: result));
            }
            catch (Exception ex)
            {
                return BadRequest(ApiResult.FAILED(ex.Message, ex));
            }
        }


        /// <summary>
        /// 模拟请求
        /// </summary>
        /// <param name="AppID"></param>
        /// <param name="ApiVersion"></param>
        /// <param name="AppSubID"></param>
        /// <param name="AppToken"></param>
        /// <param name="OrganiID"></param>
        /// <param name="SysID"></param>
        /// <returns></returns>
        [HttpGet]
        public async Task<IActionResult> Response(
            string AppID = "INTE.EXTSYS.MES.MOAsync",
            string ApiVersion = "V1.0",
            string AppSubID = "0099999999A0001",
            string AppToken = "a758b7e7afb94f3fa173dd3e64a1555b",
            string OrganiID = "00999999999",
            string SysID = "0099999999A")
        {
            StringBuilder url = new StringBuilder();
            url.Append(@$"AppID={AppID}");
            url.Append(@$"&ApiVersion={ApiVersion}");
            url.Append(@$"&AppSubID={AppSubID}");
            url.Append(@$"&AppToken={AppToken}");
            url.Append(@$"&OrganiID={OrganiID}");
            url.Append(@$"&Sign=NO_SIGN");
            url.Append(@$"&SysID={SysID}");
            url.Append(@$"&TimeStamp={DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss:fff")}");
            url.Append("&UserToken=");


            //var json = "{\"date\":\"2023-08-29T11:09:40.3572398+08:00\",\"temperatureC\":3,\"temperatureF\":37,\"summary\":\"Hot\"}";
            //HttpContent content = new StringContent(json);
            //content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue("application/json");


            //var requstUrl = Request.Scheme + "://" + Request.Host + "/api/HttpRequst/Requst?ssdp=";
            var requstUrl = Request.Scheme + "://" + Request.Host + "/api/HttpRequst/Requst?ssdp=";
            StringBuilder builder = new StringBuilder(requstUrl);
            builder.Append(Encrypt.Base64Encode(url.ToString(), "utf-8"));
            builder.Append("&page=1&pageSize=50");

            var result = await new MyHttpClient().GetAsync(builder.ToString());
            //var result = await new MyHttpClient().PostAsync(builder.ToString(), content);

            return Ok(result);
        }


        public static LogisticsCode LogisticsMapping(LogisticsName name)
        {
            switch (name)
            {
                case LogisticsName.shunfeng: return LogisticsCode.SF;
                case LogisticsName.ems: return LogisticsCode.EMS;
                //case LogisticsName.shunfeng:return LogisticsCode.EYB;
                case LogisticsName.zhaijisong: return LogisticsCode.ZJS;
                case LogisticsName.zhongtong: return LogisticsCode.ZTO;
                case LogisticsName.yuantong: return LogisticsCode.YTO;
                case LogisticsName.huitongkuaidi: return LogisticsCode.HTKY;
                case LogisticsName.youshuwuliu: return LogisticsCode.UC;
                case LogisticsName.shentong: return LogisticsCode.STO;
                case LogisticsName.tiantian: return LogisticsCode.TTKDEX;
                case LogisticsName.quanfengkuaidi: return LogisticsCode.QFKD;
                case LogisticsName.kuaijiesudi: return LogisticsCode.FAST;
                case LogisticsName.youzhengbk: return LogisticsCode.POSTB;
                case LogisticsName.guotongkuaidi: return LogisticsCode.GTO;
                case LogisticsName.yunda: return LogisticsCode.YUNDA;
                case LogisticsName.jd: return LogisticsCode.JD;
                //case LogisticsName.shunfeng:return LogisticsCode.DD;
                case LogisticsName.yamaxunwuliu: return LogisticsCode.AMAZON;
                case LogisticsName.amazoncnorder: return LogisticsCode.AMAZON;
                default:
                    return LogisticsCode.OTHER;
            }
        }


    }


    public class Result
    {
        public string status { get; set; }

        public string message { get; set; }
        public object result { get; set; }
    }

    public class Param
    {
        /// <summary>
        /// 服务编码
        /// </summary>
        public string? AppID { get; set; }
        /// <summary>
        /// 服务版本
        /// </summary>
        public string? ApiVersion { get; set; }
        /// <summary>
        /// 应用编码
        /// </summary>
        public string? AppSubID { get; set; }
        /// <summary>
        /// 应用授权令牌
        /// </summary>
        public string? AppToken { get; set; }
        /// <summary>
        /// 组织编码
        /// </summary>
        public string? OrganiID { get; set; }
        public string? Sign { get; set; }
        /// <summary>
        /// 系统编码
        /// </summary>
        public string? SysID { get; set; }
        /// <summary>
        /// 请求时间戳
        /// </summary>
        public string? TimeStamp { get; set; }
        /// <summary>
        /// 用户Token
        /// </summary>
        public string? UserToken { get; set; }
    }


    public enum LogisticsName
    {
        /// <summary>
        /// 安能快递
        /// </summary>
        ane66,
        /// <summary>
        /// 安能快运
        /// </summary>
        annengwuliu,
        /// <summary>
        /// 安得物流
        /// </summary>
        annto,
        /// <summary>
        /// 方舟速递
        /// </summary>
        arkexpress,
        /// <summary>
        /// 澳邮中国快运
        /// </summary>
        auexpress,
        /// <summary>
        /// 百世快运
        /// </summary>
        baishiwuliu,
        /// <summary>
        /// 斑马物流
        /// </summary>
        banma,
        /// <summary>
        /// 邦泰快运
        /// </summary>
        btexpress,
        /// <summary>
        /// 哥斯达黎加(Correos de Costa Rica)
        /// </summary>
        correos,
        /// <summary>
        /// 中远e环球
        /// </summary>
        cosco,
        /// <summary>
        /// 丹鸟
        /// </summary>
        danniao,
        /// <summary>
        /// 德邦快递
        /// </summary>
        debangkuaidi,
        /// <summary>
        /// 德坤物流
        /// </summary>
        dekuncn,
        /// <summary>
        /// DHL-中国件
        /// </summary>
        dhl,
        /// <summary>
        /// DHL-全球件
        /// </summary>
        dhlen,
        /// <summary>
        /// 递四方
        /// </summary>
        disifang,
        /// <summary>
        /// DPD Germany
        /// </summary>
        dpdgermany,
        /// <summary>
        /// D速快递
        /// </summary>
        dsukuaidi,
        /// <summary>
        /// EMS
        /// </summary>
        ems,
        /// <summary>
        /// EWE全球快递
        /// </summary>
        ewe,
        /// <summary>
        /// Fedex-国际件-中文
        /// </summary>
        fedexcn,
        /// <summary>
        /// 日日顺智慧物联
        /// </summary>
        gooday365,
        /// <summary>
        /// 如家国际快递
        /// </summary>
        homecourier,
        /// <summary>
        /// 锦程快递
        /// </summary>
        hrex,
        /// <summary>
        /// 汇森速运
        /// </summary>
        huisenky,
        /// <summary>
        /// 百世快递
        /// </summary>
        huitongkuaidi,
        /// <summary>
        /// 日本郵便
        /// </summary>
        japanpost,
        /// <summary>
        /// 日本（Japan Post）
        /// </summary>
        japanposten,
        /// <summary>
        /// 京东物流
        /// </summary>
        jd,
        /// <summary>
        /// 加运美
        /// </summary>
        jiayunmeiwuliu,
        /// <summary>
        /// 京广速递
        /// </summary>
        jinguangsudikuaijian,
        /// <summary>
        /// 极兔速递
        /// </summary>
        jtexpress,
        /// <summary>
        /// 聚鼎物流
        /// </summary>
        juding,
        /// <summary>
        /// 跨越速运
        /// </summary>
        kuayue,
        /// <summary>
        /// 联昊通
        /// </summary>
        lianhaowuliu,
        /// <summary>
        /// 特急送
        /// </summary>
        lntjs,
        /// <summary>
        /// 美国快递
        /// </summary>
        meiguokuaidi,
        /// <summary>
        /// 平安达腾飞
        /// </summary>
        pingandatengfei,
        /// <summary>
        /// 佐川急便
        /// </summary>
        sagawa,
        /// <summary>
        /// 盛丰物流
        /// </summary>
        sfwl,
        /// <summary>
        /// 申通快递
        /// </summary>
        shentong,
        /// <summary>
        /// 顺丰快递
        /// </summary>
        shunfeng,
        /// <summary>
        /// 顺丰快运
        /// </summary>
        shunfengkuaiyun,
        /// <summary>
        /// 签收快递
        /// </summary>
        signedexpress,
        /// <summary>
        /// 速必达
        /// </summary>
        subida,
        /// <summary>
        /// 顺达快递
        /// </summary>
        sundarexpress,
        /// <summary>
        /// 速通物流
        /// </summary>
        sut56,
        /// <summary>
        /// 广东速腾物流
        /// </summary>
        suteng,
        /// <summary>
        /// 顺心捷达
        /// </summary>
        sxjdfreight,
        /// <summary>
        /// SYNSHIP快递
        /// </summary>
        synship,
        /// <summary>
        /// 世华通物流
        /// </summary>
        szshihuatong56,
        /// <summary>
        /// 黑猫宅急便
        /// </summary>
        tcat,
        /// <summary>
        /// 泰国（Thailand Thai Post）
        /// </summary>
        thailand,
        /// <summary>
        /// 天地华宇
        /// </summary>
        tiandihuayu,
        /// <summary>
        /// 天天快递
        /// </summary>
        tiantian,
        /// <summary>
        /// TST速运通
        /// </summary>
        tstexp,
        /// <summary>
        /// 德国优拜物流
        /// </summary>
        ubuy,
        /// <summary>
        /// UPS
        /// </summary>
        ups,
        /// <summary>
        /// 易境达国际物流
        /// </summary>
        uscbexpress,
        /// <summary>
        /// 威时沛运货运
        /// </summary>
        wtdchina,
        /// <summary>
        /// 信丰物流
        /// </summary>
        xinfengwuliu,
        /// <summary>
        /// YDH
        /// </summary>
        ydhex,
        /// <summary>
        /// 壹米滴答
        /// </summary>
        yimidida,
        /// <summary>
        /// 优速快递
        /// </summary>
        youshuwuliu,
        /// <summary>
        /// 邮政标准快递
        /// </summary>
        youzhengbk,
        /// <summary>
        /// 国际包裹
        /// </summary>
        youzhengguoji,
        /// <summary>
        /// 邮政快递包裹
        /// </summary>
        youzhengguonei,
        /// <summary>
        /// 圆通速递
        /// </summary>
        yuantong,
        /// <summary>
        /// 圆通快运
        /// </summary>
        yuantongkuaiyun,
        /// <summary>
        /// 韵达快递
        /// </summary>
        yunda,
        /// <summary>
        /// 韵达快运
        /// </summary>
        yundakuaiyun,
        /// <summary>
        /// 宅急便
        /// </summary>
        zhaijibian,
        /// <summary>
        /// 中铁飞豹
        /// </summary>
        zhongtiewuliu,
        /// <summary>
        /// 中通快递
        /// </summary>
        zhongtong,
        /// <summary>
        /// 中通国际
        /// </summary>
        zhongtongguoji,
        /// <summary>
        /// 中通快运
        /// </summary>
        zhongtongkuaiyun,
        /// <summary>
        /// 宅急送
        /// </summary>
        zhaijisong,
        /// <summary>
        /// 全峰快递
        /// </summary>
        quanfengkuaidi,
        /// <summary>
        /// 快捷速递
        /// </summary>
        kuaijiesudi,
        /// <summary>
        /// 国通快递
        /// </summary>
        guotongkuaidi,
        /// <summary>
        /// 亚马逊物流
        /// </summary>
        yamaxunwuliu,
        /// <summary>
        /// 亚马逊中国订单
        /// </summary>
        amazoncnorder
    }
    public enum LogisticsCode
    {
        /// <summary>
        /// 顺丰
        /// </summary>
        SF,
        /// <summary>
        /// 标准快递
        /// </summary>
        EMS,
        /// <summary>
        /// 经济快件
        /// </summary>
        EYB,
        /// <summary>
        /// 宅急送
        /// </summary>
        ZJS,
        /// <summary>
        /// 圆通
        /// </summary>
        YTO,
        /// <summary>
        /// 中 通
        /// </summary>
        ZTO,
        /// <summary>
        /// 百世汇通
        /// </summary>
        HTKY,
        /// <summary>
        /// 优速
        /// </summary>
        UC,
        /// <summary>
        /// 申通
        /// </summary>
        STO,
        /// <summary>
        /// 天天快递
        /// </summary>
        TTKDEX,
        /// <summary>
        /// 全峰
        /// </summary>
        QFKD,
        /// <summary>
        /// 快捷
        /// </summary>
        FAST,
        /// <summary>
        /// 邮政小包
        /// </summary>
        POSTB,
        /// <summary>
        /// 国通
        /// </summary>
        GTO,
        /// <summary>
        /// 韵达
        /// </summary>
        YUNDA,
        /// <summary>
        /// 京东配送
        /// </summary>
        JD,
        /// <summary>
        /// 当当宅配
        /// </summary>
        DD,
        /// <summary>
        /// 亚马逊物流
        /// </summary>
        AMAZON,
        /// <summary>
        /// 其他
        /// </summary>
        OTHER
    }

    
}
